<!doctype html>
<html>
  <body>
    <script src="three.js"></script>
    <script>
      const renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true,
      });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      renderer.setAnimationLoop(animate);

      const scene = new THREE.Scene();
      scene.matrixAutoUpdate = false;
      // scene.background = new THREE.Color(0x3B3961);

      const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
      // camera.position.set(0, 1, 0);
      // camera.lookAt(new THREE.Vector3());
      scene.add(camera);

      const ambientLight = new THREE.AmbientLight(0x808080);
      scene.add(ambientLight);

      const directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1);
      directionalLight.position.set(1, 1, 1);
      scene.add(directionalLight);

      // canvas

      const canvas = document.createElement('canvas');
      canvas.width = 1024;
      canvas.height = 1024;
      // document.body.appendChild(canvas);

      const ctx = canvas.getContext('2d');
      ctx.fillStyle = '#FFFFFF';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = '#FF0000';
      ctx.fillRect(100, 100, 300, 300);
      // ctx.font = '30px Arial';
      // ctx.fillText('lol', 512, 512);

      (() => {
        const texture = new THREE.Texture(
          canvas/*,
          THREE.UVMapping,
          THREE.ClampToEdgeWrapping,
          THREE.ClampToEdgeWrapping,
          THREE.NearestFilter,
          THREE.NearestFilter,
          THREE.RGBAFormat,
          THREE.UnsignedByteType,
          1 */
        );
        texture.needsUpdate = true;
        
        const img = new Image();
        img.crossOrigin = 'Anonymous';
        img.onload = () => {
          ctx.drawImage(img, 200, 200, 300, 300);

          const imageData = ctx.getImageData(100, 100, 300, 300);
          ctx.putImageData(imageData, 100, 500);

          texture.needsUpdate = true;

          createImageBitmap(img)
            .then(imageBitmap => {
              ctx.drawImage(imageBitmap, 500, 0);
              texture.needsUpdate = true;
            })
            .then(() =>
              createImageBitmap(img, {
                imageOrientation: 'flipY',
              })
              .then(imageBitmap => {
                ctx.drawImage(imageBitmap, 500, 500);
                texture.needsUpdate = true;
              })
            )
            .catch(err => {
              console.warn(err.stack);
            });
        };
        img.onerror = err => {
          console.warn(err);
        };
        img.src = 'test.jpg';

        const planeMesh = (() => {
          const geometry = new THREE.PlaneBufferGeometry(0.8, 0.8);
          const material = new THREE.MeshBasicMaterial({
            map: texture,
            // color: 0xFF0000,
          });
          const mesh = new THREE.Mesh(geometry, material);
          mesh.position.z = -1;
          mesh.updateMatrixWorld();
          return mesh;
        })();
        scene.add(planeMesh);
      })();

      (() => {
        const texture = new THREE.Texture();
        texture.flipY = false;
        
        const img = new Image();
        img.crossOrigin = 'Anonymous';
        img.onload = () => {
          texture.image = img;
          texture.needsUpdate = true;
        };
        img.onerror = err => {
          console.warn(err);
        };
        img.src = 'test.jpg';

        const imageMesh = (() => {
          const geometry = new THREE.PlaneBufferGeometry(0.5, 0.5);
          const material = new THREE.MeshBasicMaterial({
            map: texture,
            // color: 0xFF0000,
          });
          const mesh = new THREE.Mesh(geometry, material);
          mesh.position.x = 0.3;
          mesh.position.z = -1;
          mesh.rotation.y = -0.5;
          mesh.rotation.order = 'YXZ';
          mesh.updateMatrixWorld();
          return mesh;
        })();
        scene.add(imageMesh);
      })();

      function animate(time, frame) {
        renderer.render(scene, renderer.vr.enabled ? renderer.vr.getCamera(camera) : camera);
      }
    </script>
  </body>
</html>
